import { Injectable } from '@nestjs/common';
import * as svgCaptcha from 'svg-captcha';
import { verify, sign, JwtPayload } from 'jsonwebtoken';
import * as nuid from 'nuid';
import { CacheService } from './cache/cache.service';
import { ConfigService } from '@nestjs/config';
import { UserService } from './user/user.service';

interface JwtParams extends JwtPayload {
  id?: string;
  type?: string;
}
@Injectable()
export class AppService {
  constructor(
    private readonly cacheService: CacheService,
    private readonly configService: ConfigService,
    private readonly userService: UserService,
  ) {}

  async getVerification() {
    const options = {
      size: 4, // 验证码长度
      fontSize: 45, // 验证码字号
      noise: 2, // 干扰线条数目
      width: 120, // 宽度
      height: 40, // 高度
      color: true, // 验证码字符是否有颜色，默认是没有，但是如果设置了背景颜色，那么默认就是有字符颜色
    };
    const Captcha = svgCaptcha.createMathExpr(options); // 生成验证码
    await this.cacheService.set(
      `img_code_${nuid.next()}`,
      Captcha.text,
      60 * 5,
    );
    return {
      data: {
        img: Captcha.data,
        nuid: nuid.next(),
      },
    };
  }

  async refreshToken(refreshToken: string) {
    if (refreshToken) {
      const decodeRefreshToken: string | JwtParams = await verify(
        refreshToken,
        this.configService.get('SECRET'),
      );
      const { id } = decodeRefreshToken as JwtParams;
      const redis_refresh_token = await this.cacheService.get(
        `refresh_token_${id}`,
      );
      if (refreshToken !== redis_refresh_token) {
        return {
          code: -1,
          msg: 'refreshToken不正确',
        };
      }
      // 获取用户信息
      const user = await this.userService.findUserById(id);
      const userInfo = user.data.dataValues;
      // 生成新的acccessToken,并且更新redis中的accessToken
      const access_token = sign(userInfo, this.configService.get('SECRET'), {
        expiresIn: +this.configService.get('ACCESS_TOKEN_EXPIRE'),
      });
      const refresh_token = sign(
        { type: 'refresh', id: userInfo.id },
        this.configService.get('SECRET'),
        {
          expiresIn: +this.configService.get('REFRESH_TOKEN_EXPIRE'),
        },
      );
      await this.cacheService.set(
        `access_token_${userInfo.id}`,
        access_token,
        +this.configService.get('ACCESS_TOKEN_EXPIRE'),
      );
      await this.cacheService.set(
        `refresh_token_${userInfo.id}`,
        refresh_token,
        +this.configService.get('REFRESH_TOKEN_EXPIRE'),
      );
      return {
        data: {
          accessToken: access_token,
          refreshToken: refresh_token,
          user: userInfo,
          exp: ~~(
            (Date.now() +
              +this.configService.get('ACCESS_TOKEN_EXPIRE') * 1000) /
            1000
          ),
        },
      };
    } else {
      return {
        code: -1,
        msg: 'refreshToken不能为空',
      };
    }
  }
}
